package ae.generator;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 * AE-模板代码生成
 * @author: zxm
 * @date: 2025/9/4
 */
public class ExecuteGenerator {

    // 模板文件路径
    private static final String TEMPLATE_DIR = "templates/";
    // 生成文件输出路径
    private static final String OUTPUT_DIR = "src/main/java/";

    // 基础包名
    private final String basePackage;
    // 模块名
    private final String moduleName;

    public ExecuteGenerator(String basePackage, String moduleName) {
        this.basePackage = basePackage;
        this.moduleName = moduleName;
    }

    /**
     * 表名及类名
     */
    public void generate(String tableName,String schemaPattern) {
        // 转换表名为类名（下划线转驼峰，首字母大写）
        String className = GenerateUtil.convertToClassName(tableName);
        generate(tableName,className,schemaPattern);
    }

    /***
     * 自定义类名
     */
    public void generate(String tableName,String className,String schemaPattern) {
        try {
            System.out.println("开始生成" + className + "的模板代码...");
            // 准备模板数据
            Map<String, String> dataModel = prepareDataModel(tableName, className,schemaPattern);
            String basePackagePath = basePackage + "." + moduleName;
            // 生成各个组件
            generateFile("domain.entity.template",
                    GenerateUtil.getPackagePath(basePackagePath,"domain.entity."),
                    className + ".java",
                    dataModel);

            generateFile("app.service.template",
                    GenerateUtil.getPackagePath(basePackagePath,"app."),
                    className + "Service.java",
                    dataModel);

            generateFile("app.impl.template",
                    GenerateUtil.getPackagePath(basePackagePath,"app.impl."),
                    className + "ServiceImpl.java",
                    dataModel);

            generateFile("domain.repository.template",
                    GenerateUtil.getPackagePath(basePackagePath,"domain.repository."),
                    className + "Repository.java",
                    dataModel);

            generateFile("infra.mapper.template",
                    GenerateUtil.getPackagePath(basePackagePath,"infra.mapper."),
                    className + "Mapper.java",
                    dataModel);

            generateFile("infra.repository.impl.template",
                    GenerateUtil.getPackagePath(basePackagePath,"infra.repository.impl."),
                    className + "RepositoryImpl.java",
                    dataModel);

            generateFile("api.controller.v1.template",
                    GenerateUtil.getPackagePath(basePackagePath,"api.controller.v1."),
                    className + "Controller.java",
                    dataModel);


        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成单个文件
     */
    private void generateFile(String templateFileName, String outputPackagePath,
                              String outputFileName, Map<String, String> dataModel) throws IOException {
        // 读取模板内容
        String templateContent = GenerateUtil.readTemplate(TEMPLATE_DIR + templateFileName);
        // 替换模板变量
        String generatedContent = GenerateUtil.replaceTemplateVariables(templateContent, dataModel);
        // 确保输出目录存在
        Path outputDir = Paths.get(OUTPUT_DIR, outputPackagePath);
        Files.createDirectories(outputDir);

        // 写入生成的文件
        Path outputFile = outputDir.resolve(outputFileName);
        Files.writeString(outputFile, generatedContent);
        System.out.println("生成文件: " + outputFile);
    }


    /**
     * 准备模板数据模型
     */
    private Map<String, String> prepareDataModel(String tableName, String className,String schemaPattern) {
        Map<String, String> dataModel = new HashMap<>();
        dataModel.put("basePackage", basePackage + "." + moduleName);
        dataModel.put("tableName", tableName);
        dataModel.put("className", GenerateUtil.firstLetterToLower(className));
        dataModel.put("ClassName", className);
        dataModel.put("rootPackage", basePackage);
        dataModel.put("class-name", GenerateUtil.convertCamelCase(className));
        dataModel.put("entityContent",getEntityContent(tableName,className,schemaPattern));
        return dataModel;
    }

    /**
     * 获取实体内容
     */
    private String getEntityContent(String tableName,String className,String schemaPattern){
        EntityGenerator entityGenerator = new EntityGenerator();
        return entityGenerator.createEntityContent(tableName,schemaPattern,className);
    }
}
